package ai.esc.speedy.common.util.id;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * 由于 Event Soucing 是记录事件的，那么 Object Id 肯定就不能是用数据库生成的了，基本上所有的 Event Soucing 相关的框架都是将事件直接序列化，
 * 然后对应到 Object，所以这种情况下，就需要自己产生 ID，而自己生成 ID 的话，就有很多限制，比如需要根据时间递增，尽量比较短，在分布式的情况下 ID 保证不能重复等。
 * <p>
 * 这里我们建立一个 UIDGenerator 作为服务的 ID 生成器，在启动的时候，通过 WorkerIdService 获取到一个 Worker ID，并构建 Snowfalke 对象，至此我们的 ID 生成器就基本完成。
 *
 * @author 周国勇
 * <p>
 * 周广明整理、添加备注
 * @version v1 2019/12/24 17:06
 */
@Component(value = "uidGenerator")
public class UIDGenerator {

    private SnowFlake flake;
    private final WorkerIdService workerIdService;

    @Autowired
    public UIDGenerator(WorkerIdService workerIdService) {
        this.workerIdService = workerIdService;
    }

    public Long getId() {
        return flake.nextId();
    }

    public String getIdStr() {
        return flake.nextId().toString();
    }

    @PostConstruct
    public void init() {
        this.flake = new SnowFlake(workerIdService.getWorkerId());
    }
}
